/**
 * Copyright (C) 2010 Sergey Grigoriev <s.a.grigoriev@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.gmf.dsl

import org.apache.maven.project.MavenProject

import org.testng.annotations.Test
import org.apache.maven.artifact.DefaultArtifact
import org.apache.maven.artifact.Artifact

import org.testng.Assert
import org.testng.annotations.BeforeMethod
import net.gmf.core.ProjectContext

class FlexBuilderTest {

  FlexProject builder

  @BeforeMethod
  private void init() {
    final MavenProject project = new MavenProject()
    project.artifact = new DefaultArtifact(
            project.groupId,
            project.artifactId,
            project.version,
            Artifact.SCOPE_COMPILE,
            'swc',
            'swc',
            null
    )

    ProjectContext ctx = new ProjectContext()
    ctx.project = project
    builder = new FlexProject()
    builder.metaClass.getBasedir = { '/var'}
    builder.ctx = ctx
  }

  private void verify(actual, expected) {
    Assert.assertEquals(evaluateGStrings(actual), expected)
  }

  @Test
  void dsl1() {

    builder.build {
      flexSdkHome '/opt/flexSdk'
    }
    Assert.assertEquals '/opt/flexSdk', builder.rootNode.flexSdkHome
  }

  @Test
  void dsl2() {

    builder.build {
      flexSdkHome '/opt/flexSdk'
      compiler {
        op '-compiler.library-path': "$basedir/lib"
      }
    }
    verify(builder.rootNode.compiler.ops, [['-compiler.library-path': '/var/lib']])
  }

  @Test
  void dsl3() {
    builder.build {
      compiler {
        out {
          op 'Main.mxml'
        }
        test {
          op 'TestRunner.mxml'
        }
      }
    }

    verify(
            builder.rootNode.compiler.out.ops, ['Main.mxml']
    )
    verify(
            builder.rootNode.compiler.test.ops, ['TestRunner.mxml']
    )
  }

  @Test
  void dsl4() {
    builder.build {
      compiler {
        out {
          op '-debug'
        }
        test {
          op '-compiler.headless-server'
        }
      }
    }

    builder.build {
      compiler {
        out {
          op 'Main.mxml'
        }
        test {
          op 'TestRunner.mxml'
        }
      }
    }

    verify(
            builder.rootNode.compiler.out.ops, ['-debug', 'Main.mxml']
    )
    verify(
            builder.rootNode.compiler.test.ops, ['-compiler.headless-server', 'TestRunner.mxml']
    )
    Assert.assertTrue builder.rootNode.copyFrameworkRsls
  }

  @Test
  void dsl5() {
    builder.build {
      compiler {
        test {
          op "-compiler.library-path+=": "${project.basedir}/../lib/flexunit"
          op '-compiler.headless-server'
        }
      }
    }
  }

  @Test
  void dsl6() {
    builder.build {
      flexSdkHome null
      compiler {
        test {
          op "-compiler.library-path+=": "${project.basedir}/../lib/flexunit"
          op '-compiler.headless-server'
        }
      }
      testRunner {
        flashPlayer null
      }
    }
  }

  @Test(expectedExceptions = MissingPropertyException.class)
  void dsl7() {
    builder.build {
      notExistingNode 33
    }
  }

  @Test
  void dsl8() {
    builder.build {
      copyFrameworkRsls false
    }
    Assert.assertFalse builder.rootNode.copyFrameworkRsls
  }

  @Test
  void props() {
    builder.build {
       props['a']=3
       props['b']= { x -> x +1 }
    }
    builder.build {
       Assert.assertEquals (props['a'], 3)
       Assert.assertEquals (props.b(6), 7)
    }
  }

  @Test
  void optimizer() {
    builder.build {
      makeRsl {
        optimizer {
           op '-compiler.debug'
        }
        artifact 'net.gmf:library-rsl:swf'
      }
    }
    Assert.assertEquals(builder.rootNode.makeRslNode.artifact, 'net.gmf:library-rsl:swf')
  }


  private def evaluateGStrings(op) {
    return op.collect {
      if (it instanceof CharSequence) return it.toString()
      if (it instanceof Map) {
        def result = [:]
        it.each {key, value ->
          def evaluated
          if (value instanceof CharSequence) {
            evaluated = value.toString()
          } else if (value instanceof Collection) {
            evaluated = value.collect { it.toString()}
          }
          result[key] = evaluated
        }
        return result
      }
      throw new IllegalArgumentException()
    }
  }
}
